package com.lcx.plugin.ui;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.intellij.icons.AllIcons;
import com.intellij.ide.fileTemplates.impl.UrlUtil;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.BrowserHyperlinkListener;
import com.intellij.util.ExceptionUtil;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import com.lcx.plugin.dict.GlobalDict;
import com.lcx.plugin.dto.ColumnIndexDTO;
import com.lcx.plugin.dto.MySettingsStorageDTO;
import com.lcx.plugin.tool.CacheDataUtils;
import com.lcx.plugin.tool.MessageDialogUtils;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;

/**
 * @author lcx
 * @version 1.0.0
 * @date 2021/08/07 09:22
 */
public class MainSettingForm implements Configurable, Configurable.Composite, MyBaseSettings {

    /**
     * 模板描述信息，说明文档
     */
    private static final String TEMPLATE_DESCRIPTION_INFO;

    static {
        String descriptionInfo = "";
        try {
            descriptionInfo = UrlUtil.loadText(MainSettingForm.class.getResource("/description/globalConfigDescription.html"));
        } catch (IOException e) {
            ExceptionUtil.rethrow(e);
        } finally {
            TEMPLATE_DESCRIPTION_INFO = descriptionInfo;
        }
    }

    private JLabel versionLabel;
    private JButton resetBtn;
    private JPanel mainPanel;
    private JTextField downloadPathField;
    private JLabel downloadTitle;
    private JButton chooseBtn;
    private JButton downloadBtn;
    private JTextField fieldField;
    private JTextField nameField;
    private JTextField typeField;
    private JLabel fieldLabel;
    private JLabel nameLabel;
    private JLabel typeLabel;
    private JTextField lengthField;
    private JTextField mustField;
    private JTextField memoField;
    private JTextField indexTypeField;
    private JTextField indexNameField;
    private JTextField indexNoteField;
    private JLabel lengthLabel;
    private JLabel mustLabel;
    private JLabel memoLabel;
    private JLabel indexTypeLabel;
    private JLabel indexNameLabel;
    private JLabel indexNoteLabel;
    private JEditorPane infoEditorPane;
    private JScrollPane infoScrollPane;
    private JLabel descriptionLabel;
    private JLabel configLabel;
    private JLabel downloadTipLabel;
    private JLabel nowVersionLabel;
    private JLabel downloadPathLabel;
    private JLabel savePwdLabel;
    private JCheckBox savePwdCheckBox;
    private JLabel mergeNameMemoLabel;
    private JCheckBox mergeNameMemoCheckBox;

    private CacheDataUtils cacheDataUtils = CacheDataUtils.getInstance();
    /**
     * 子配置
     */
    private Configurable[] childConfigurableArray;

    public MainSettingForm() {
    }

    @Override
    public String getDisplayName() {
        return "EasyDB";
    }

    @Nullable
    @Override
    public String getHelpTopic() {
        return getDisplayName();
    }

    @Override
    public Configurable[] getConfigurables() {
        this.childConfigurableArray = new Configurable[]{
                new TypeMapperSettingForm()
        };
        this.loadChildSettingsStore(getSettingsStorage());
        return this.childConfigurableArray;
    }

    private void loadChildSettingsStore(MySettingsStorageDTO mySettingsStorageDTO) {
        // 初始装置配置信息
        for (Configurable configurable : this.childConfigurableArray) {
            if (configurable instanceof MyBaseSettings) {
                ((MyBaseSettings) configurable).loadSettingsStore(mySettingsStorageDTO);
            }
        }
    }

    @Override
    public @Nullable
    JComponent createComponent() {
        // 初始图标
        this.downloadTitle.setIcon(AllIcons.Actions.IntentionBulb);
        // 加载储存数据
        this.loadSettingsStore();
        // 初始化事件
        this.initEvent();
        // 初始化描述信息
        this.initRemarkPanel();

        return mainPanel;
    }

    /**
     * 初始化事件
     *
     * @return void
     * @author daxiong
     * @date 2023/6/21 下午2:40
     */
    private void initEvent() {
        this.resetBtn.addActionListener(e -> {
            boolean result = MessageDialogUtils.yesNo("确认恢复默认设置，所有配置信息将被重置。确认继续？");
            if (result) {
                // 重置默认值后重新加载配置
                MySettingsStorageDTO mySettingsStorageDTO = getSettingsStorage().resetDefaultVal();
                this.loadSettingsStore(mySettingsStorageDTO);
                this.loadChildSettingsStore(mySettingsStorageDTO);
            }
        });

        // 下载模板的路径选择
        chooseBtn.addActionListener(e -> {
            VirtualFile virtualFile = FileChooser.chooseFile(FileChooserDescriptorFactory.createSingleFolderDescriptor(), cacheDataUtils.getProject(), null);
            if (virtualFile != null) {
                String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                downloadPathField.setText(virtualFile.getPath() + "/template-" + format + ".xlsx");
            } else {
                Messages.showWarningDialog("没有选择到文件夹！", GlobalDict.TITLE_INFO);
            }
        });

        downloadBtn.addActionListener(e -> {
            String downloadTemplateFieldText = downloadPathField.getText();
            if (StrUtil.isBlank(downloadTemplateFieldText)) {
                Messages.showWarningDialog("模板下载路径不能为空！", GlobalDict.TITLE_INFO);
                return;
            }
            File ioFile = new File(downloadTemplateFieldText);
            try {
                // 创建文件
                ioFile.createNewFile();
                if (!ioFile.isFile()) {
                    Messages.showWarningDialog("请填写正确的文件路径！", GlobalDict.TITLE_INFO);
                    return;
                }
                InputStream inputStream = SelectFile.class.getResourceAsStream("/template.xlsx");
                FileUtil.writeFromStream(inputStream, ioFile);
                Messages.showInfoMessage("下载模板成功！", GlobalDict.TITLE_INFO);
            } catch (IOException exception) {
                exception.printStackTrace();
                Messages.showWarningDialog("下载模板失败！", GlobalDict.TITLE_INFO);
            }
        });
    }

    /**
     * 初始化描述信息
     *
     * @return void
     * @author daxiong
     * @date 2023/6/21 下午2:39
     */
    private void initRemarkPanel() {
        // 描述信息
        // html形式展示
        infoEditorPane.setEditorKit(UIUtil.getHTMLEditorKit());
        // 仅查看
        infoEditorPane.setEditable(false);
        infoEditorPane.setText(TEMPLATE_DESCRIPTION_INFO);
        // 添加浏览器链接监听事件
        infoEditorPane.addHyperlinkListener(new BrowserHyperlinkListener());
        infoScrollPane.setPreferredSize(JBUI.size(300, 150));
    }

    /**
     * idea会定时执行，查看是否修改了配置
     */
    @Override
    public boolean isModified() {
        if (!Objects.equals(this.downloadPathField.getText(), getSettingsStorage().getTemplateDownloadPath())) {
            return true;
        }
        if (!Objects.equals(this.savePwdCheckBox.isSelected(), getSettingsStorage().isRememberPwd())) {
            return true;
        }
        if (!Objects.equals(this.mergeNameMemoCheckBox.isSelected(), getSettingsStorage().isMergeNameMemo())) {
            return true;
        }
        ColumnIndexDTO columnIndexDTO = giveValue();
        if (!Objects.equals(columnIndexDTO, getSettingsStorage().getColumnIndexDTO())) {
            return true;
        }
        return false;
    }

    /**
     * 点击apply触发
     *
     * @return void
     * @author daxiong
     * @date 2023/6/21 下午2:39
     */
    @Override
    public void apply() throws ConfigurationException {
        String downloadPath = this.downloadPathField.getText();
        this.getSettingsStorage().setTemplateDownloadPath(downloadPath);

        this.getSettingsStorage().setRememberPwd(this.savePwdCheckBox.isSelected());
        this.getSettingsStorage().setMergeNameMemo(this.mergeNameMemoCheckBox.isSelected());

        ColumnIndexDTO columnIndexDTO = giveValue();
        this.getSettingsStorage().setColumnIndexDTO(columnIndexDTO);
    }

    private ColumnIndexDTO giveValue() {
        String fieldFieldText = this.fieldField.getText();
        String nameFieldText = this.nameField.getText();
        String typeFieldText = this.typeField.getText();
        String lengthFieldText = this.lengthField.getText();
        String mustFieldText = this.mustField.getText();
        String memoFieldText = this.memoField.getText();
        String indexTypeFieldText = this.indexTypeField.getText();
        String indexNameFieldText = this.indexNameField.getText();
        String indexNoteFieldText = this.indexNoteField.getText();
        if (StrUtil.isBlank(fieldFieldText) || StrUtil.isBlank(nameFieldText)
                || StrUtil.isBlank(typeFieldText) || StrUtil.isBlank(lengthFieldText)
                || StrUtil.isBlank(mustFieldText) || StrUtil.isBlank(memoFieldText)
                || StrUtil.isBlank(indexTypeFieldText) || StrUtil.isBlank(indexNameFieldText)
                || StrUtil.isBlank(indexNoteFieldText)) {
            Messages.showWarningDialog("下标设置不能为空！", GlobalDict.TITLE_INFO);
        }
        try {
            ColumnIndexDTO columnIndexDTO = new ColumnIndexDTO();
            columnIndexDTO.setField(Integer.parseInt(fieldFieldText));
            columnIndexDTO.setName(Integer.parseInt(nameFieldText));
            columnIndexDTO.setType(Integer.parseInt(typeFieldText));
            columnIndexDTO.setLength(Integer.parseInt(lengthFieldText));
            columnIndexDTO.setMust(Integer.parseInt(mustFieldText));
            columnIndexDTO.setMemo(Integer.parseInt(memoFieldText));
            columnIndexDTO.setIndexType(Integer.parseInt(indexTypeFieldText));
            columnIndexDTO.setIndexName(Integer.parseInt(indexNameFieldText));
            columnIndexDTO.setIndexNote(Integer.parseInt(indexNoteFieldText));
            return columnIndexDTO;
        } catch (NumberFormatException e) {
            e.printStackTrace();
            Messages.showWarningDialog("只能输入0及以上的数字！", GlobalDict.TITLE_INFO);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 加载配置信息
     *
     * @param settingsStorage 配置信息
     */
    @Override
    public void loadSettingsStore(MySettingsStorageDTO settingsStorage) {
        this.versionLabel.setText(GlobalDict.VERSION);
        this.downloadPathField.setText(settingsStorage.getTemplateDownloadPath());
        this.savePwdCheckBox.setSelected(settingsStorage.isRememberPwd());
        this.mergeNameMemoCheckBox.setSelected(settingsStorage.isMergeNameMemo());
        ColumnIndexDTO columnIndexDTO = settingsStorage.getColumnIndexDTO();
        this.fieldField.setText(columnIndexDTO.getField() + "");
        this.nameField.setText(columnIndexDTO.getName() + "");
        this.typeField.setText(columnIndexDTO.getType() + "");
        this.lengthField.setText(columnIndexDTO.getLength() + "");
        this.mustField.setText(columnIndexDTO.getMust() + "");
        this.memoField.setText(columnIndexDTO.getMemo() + "");
        this.indexTypeField.setText(columnIndexDTO.getIndexType() + "");
        this.indexNameField.setText(columnIndexDTO.getIndexName() + "");
        this.indexNoteField.setText(columnIndexDTO.getIndexNote() + "");
    }
}
